package com.ccb.sc.common.modules.common.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//psl import com.ccb.sc.common.bind.exception.BizException;
import com.ccb.sc.common.code.BizCodeFace;
import com.ccb.sc.common.code.ErrorCode;
import com.ccb.sc.common.modules.common.convert.DistrictConvert;
import com.ccb.sc.common.modules.common.entity.District;
import com.ccb.sc.common.modules.common.service.IDistrictService;
import com.ccb.sc.common.modules.common.mapper.DistrictMapper;
import com.ccb.sc.common.modules.common.vo.AddressInfoVo;
import com.ccb.sc.common.modules.common.vo.DistrictVo;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 行政区 服务实现类
 * </p>
 *
 * @author ken
 * @since 2020-05-19
 */
@Service
public class DistrictServiceImpl extends ServiceImpl<DistrictMapper, District> implements IDistrictService {

    private final static Logger LOGGER = LoggerFactory.getLogger(IDistrictService.class);

    private static final String URI = "https://apis.map.qq.com";

    @Value("${tx.lbs.key:EKUBZ-ED76W-QZKRC-OCBQQ-MM5T3-RPFGN}")
    private String key;

    @Value("${tx.lbs.secretkey:Tq1ycSCkJuMxshtVVg5y2PMWM5GmSexu}")
    private String secretKey;

    private static final Integer DISTRICT_LEVEL_MAX = 3;


    @Override
    public List<DistrictVo> getDistrictTreeByLevel(Integer level) {
        if (level == null) {
            return null;
        }

        if (level < 1 || level > DISTRICT_LEVEL_MAX) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.PARAM_ERROR));
        }

        //查询行政区数据 格式:Map<行政区等级,Map<父行政区ID,该父级行政区下的行政区列表>>
        Map<Integer, Map<Long, List<District>>> data = new LinkedHashMap<>();
        for (int i = 1; i <= level; i++) {
            QueryWrapper<District> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(District::getLevel, i);

            List<District> districts = this.list(wrapper);

            Map<Long, List<District>> parentDistrictMap = new LinkedHashMap<>();
            districts.forEach(district -> {
                Long parentId = district.getParentId();
                if (!parentDistrictMap.containsKey(parentId)) {
                    parentDistrictMap.put(parentId, new LinkedList<>());
                }

                parentDistrictMap.get(parentId).add(district);
            });

            data.put(i, parentDistrictMap);
        }

        //数据结构数据组装
        List<DistrictVo> districtVos = new ArrayList<>();

        data.get(1).get(null).forEach(provinceDistrict -> {
            DistrictVo districtVo = DistrictConvert.INSTANCE.entity2Vo(provinceDistrict);
            districtVos.add(districtVo);
            this.assembly(data, districtVo);

        });

        return districtVos;
    }

    /**
     * 组装子行政区数据
     *
     * @param data       行政区数据
     * @param districtVo 当前行政区
     */
    private void assembly(Map<Integer, Map<Long, List<District>>> data, DistrictVo districtVo) {
        if (!data.containsKey(districtVo.getLevel() + 1)) {
            return;
        }
        List<District> childrenDistricts = data.get(districtVo.getLevel() + 1).get(districtVo.getId());
        if (CollectionUtils.isEmpty(childrenDistricts)) {
            return;
        }
        districtVo.setChildren(DistrictConvert.INSTANCE.entity2ListVo(childrenDistricts));
        districtVo.getChildren().forEach(childrenDistrict -> this.assembly(data, childrenDistrict));

    }

    @Override
    public AddressInfoVo locateDistrict(BigDecimal latitude, BigDecimal longitude) {
        StringBuilder params = new StringBuilder();
        params.append("/ws/geocoder/v1?key=").append(this.key).append("&location=").append(latitude).append(",").append(longitude);
        String basicString = params.toString();
        AddressInfoVo vo = new AddressInfoVo();

        //生成签名
        String sig = DigestUtils.md5Hex(basicString + secretKey);
        String requestUri = URI + params.toString() + "&sig=" + sig;
        RestTemplate restTemplate = new RestTemplate();
        JSONObject returnObject = restTemplate.getForObject(requestUri, JSONObject.class);

        LOGGER.debug("request tx lbs url: [{}], return: [{}]", requestUri, returnObject.toJSONString());
        if (returnObject.getInteger("status") == 0) {
            JSONObject result = returnObject.getJSONObject("result");
            vo = result.getObject("ad_info", AddressInfoVo.class);

            Long id = Long.parseLong(vo.getAdcode());
            //补充数据
            District district = this.getById(id);
            if (district != null) {
                String[] ids = (district.getParentIds() + id).split("/");
                vo.setParentIds(district.getParentIds());
                vo.setProvinceId(ids.length >= 1 ? Long.parseLong(ids[0]) : null);
                vo.setCityId(ids.length >= 2 ? Long.parseLong(ids[1]) : null);
                vo.setDistrictId(ids.length >= 3 ? Long.parseLong(ids[2]) : null);
            }
        }

        return vo;
    }
}
